package com.feature50.makeover.utils;

import org.apache.log4j.Logger;

import java.lang.reflect.Method;

import com.feature50.makeover.utils.ReflectionUtils;

public class StringUtils {
    private static final Logger logger = Logger.getLogger(StringUtils.class);

    public static boolean nullOrEmptyOrWhitespace(String s) {
        if (s == null)
            return true;
        return (nullOrEmpty(s.trim()));
    }

    public static boolean notNullOrEmptyOrWhitespace(String s) {
        return !nullOrEmptyOrWhitespace(s);
    }

    public static boolean nullOrEmpty(String s) {
        return (s == null) || "".equals(s);
    }

    public static boolean notNullOrEmpty(String s) {
        return !nullOrEmpty(s);
    }

    public static void trimProperties(String[] properties, Object o) {
        for (int i = 0; i < properties.length; i++) {
            String property = properties[i];
            trimProperty(property, o);
        }
    }

    // string equals comparison that handles nulls and ignores trailing spaces
    public static boolean comp(String s1, String s2) {
        if (nullOrEmptyOrWhitespace(s1)) {
            if (nullOrEmptyOrWhitespace(s2))
                return true;
            else
                return false;
        }
        if (nullOrEmptyOrWhitespace(s2))
            return false;
        return s1.trim().equals(s2.trim());
    }

    public static void trimProperty(String property, Object o) {
        try {
            Method getterMethod = ReflectionUtils.getGetterMethod(o.getClass(), property);
            String value = (String) getterMethod.invoke(o);
            value = value.trim();
            Method setterMethod = ReflectionUtils.getSetterMethod(o.getClass(), property, String.class);
            setterMethod.invoke(o, new Object[] { value });
        } catch (Exception e) {
            logger.error("Couldn't trim property \"" + property + "\" on instance of \"" + o.getClass().getName()
                    + "\"", e);
        }
    }

    public static boolean toBoolean(String bool) {
        if (bool == null)
            return false;

        String[] values = new String[] { "true", "affirmative", "yes", "aye-aye", "three-cheers-for-the-gipper",
                "uh-huh", "y", "t", "1", "roger-wilco", "roger" };
        String b = bool.toLowerCase();
        for (String v : values) {
            if (b.equals(v))
                return true;
        }
        return false;
    }

    public static String trimSuffix(String string, String suffix) {
        return string.substring(0, string.lastIndexOf(suffix));
    }

    public static String trimToMax(String s, int max) {
        if (StringUtils.nullOrEmpty(s)) return s;
        if (s.trim().length() <= max) return s.trim();
        return s.substring(0, max);
    }

    public static String firstUpperCase(String string) {
        if (StringUtils.nullOrEmpty(string))  return string;
        if (string.length() == 1) return string.toUpperCase();
        return string.substring(0, 1).toUpperCase() + string.substring(1).toLowerCase();
    }

    public static String defaultValue(String value, String defaultValue) {
        return (StringUtils.nullOrEmpty(value)) ? defaultValue : value;
    }

    public static String strip(String string, String toRemoveRegex) {
        String[] s = string.split(toRemoveRegex);
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < s.length; i++)
            sb.append(s[i]);
        return sb.toString();
    }

    /**
     * Parses fixed-width text into lines, wrapping if necessary at the column
     * boundary specified
     *
     * @param source
     * @param cols
     * @return
     */
    public static String[] parseLines(String source, int cols) {
        int line = 0;
        int lastspace = -1;
        int column = -1;
        String[] lines = new String[5];
        StringBuffer currentLine = new StringBuffer();

        for (int i = 0; i < source.length(); i++) {
            char c = source.charAt(i);

            if (c == '\n') {
                lines[line] = currentLine.toString();
                currentLine = new StringBuffer();
                lastspace = -1;
                column = -1;
                line++;
                continue;
            }

            column++;

            if (c == ' ')
                lastspace = column;

            if (column >= cols) {
                // if there aren't any spaces, just wrap the current character
                if (lastspace == -1) {
                    lines[line] = currentLine.toString();
                    currentLine = new StringBuffer();
                    currentLine.append(c);
                    column = 0;
                    line++;
                } else {
                    // if there is a space, capture everything from the space to
                    // the end and wrap
                    if (lastspace == column) {
                        lines[line] = currentLine.toString();
                        currentLine = new StringBuffer();
                        column = 0;
                        line++;
                    } else {
                        lines[line] = currentLine.substring(0, lastspace);
                        String leftover = currentLine.substring(lastspace + 1);
                        currentLine = new StringBuffer();
                        currentLine.append(leftover);
                        currentLine.append(c);
                        column = currentLine.length() - 1;
                        line++;
                    }
                }
            } else {
                currentLine.append(c);
            }
        }
        lines[line] = currentLine.toString();

        return lines;
    }

    /**
     * Removes all the HTML/XML tags from a String. Replaces &lt;br&gt; and
     * &lt;p&gt; with spaces.
     *
     * @param source
     * @return
     */
    public static String removeMarkup(String source) {
        // replace all <br> tags with spaces
        String[] spaceTags = { "br", "p" };
        for (int i = 0; i < spaceTags.length; i++) {
            source = source.replaceAll("\\<" + spaceTags[i] + "\\>", " ");
            source = source.replaceAll("\\<" + spaceTags[i] + " /\\>", " ");
            source = source.replaceAll("\\<" + spaceTags[i] + "/\\>", " ");
        }

        // remove all remaining tags
        source = source.replaceAll("\\<[^\\>]+\\>", "");

        return source;
    }

    public static final String getNonNull(String s) {
        return (s == null) ? "" : s;
    }
}